import { Algorithm } from "../types"

// Schema 定义
interface DHCDSNode {
  id: any
  type: string
  attributes: Record<string, any>
}

interface DHCDSEdge {
  source: any
  target: any
  type?: string
  weight?: number
  attributes: Record<string, any>
}

interface DHCDSGraph {
  nodes: DHCDSNode[]
  edges: DHCDSEdge[]
}

interface Community {
  id: string
  nodes: any[]
  stability: number
  description: string
}

interface DHCDSTimeStepResult {
  time: number
  communities: Community[]
  node_communities: Record<string, string[]>
}

interface DHCDSInputParams {
  graph_sequence: DHCDSGraph[]
  stability_weight: number
  embedding_dim: number
  num_clusters: number
  node_type_weights?: Record<string, number>
}

interface DHCDSOutputParams {
  results: DHCDSTimeStepResult[]
  algorithm: string
  parameters: Record<string, any>
  community_evolution: Record<string, any>[]
}

interface AlgorithmRequest {
  task_id: string
  task_callback_url?: string
  input_params: {
    graph: {
      nodes: {
        id: string
        type: string
        properties: Record<string, any>
      }[]
      edges: {
        source: string
        target: string
        type?: string
        properties: Record<string, any>
      }[]
    }
    hidden_dims: number[]
    learning_rate: number
    epochs: number
    task: string
    labels?: Record<string, number>
  }
}

// 算法实现
export const hgcnGraph: Algorithm = {
  name: "异构图神经网络(HGCN)算法",
  description: "基于异构图卷积神经网络的社区检测和节点分类算法，能够处理包含不同类型节点和边的图结构数据",
  configOptions: [
    {
      id: "embedding_dim",
      label: "嵌入维度",
      type: "number",
      defaultValue: 128,
      placeholder: "128"
    },
    {
      id: "hidden_layers",
      label: "隐藏层维度",
      type: "textarea",
      defaultValue: "[64, 32]",
      placeholder: "[64, 32]"
    },
    {
      id: "learning_rate",
      label: "学习率",
      type: "number",
      defaultValue: 0.005,
      placeholder: "0.005"
    },
    {
      id: "epochs",
      label: "训练轮次",
      type: "number",
      defaultValue: 100,
      placeholder: "100"
    },
    {
      id: "task",
      label: "任务类型",
      type: "select",
      options: [
        "node_classification",
        "community_detection"
      ],
      defaultValue: "node_classification"
    },
    {
        id: "labels",
        label: "节点标签",
        type: "textarea",
        placeholder: "{'person_1': 0, 'person_2': 0, 'company_1': 1, 'product_1': 2, 'product_2': 2}"
      },
    {
      id: "inputData",
      label: "输入数据",
      type: "textarea",
      placeholder: `请输入JSON格式的图数据，例如：
{
  "nodes": [
    {
      "id": "person_1",
      "type": "person",
      "properties": {
        "name": "张三",
        "age": 35
      }
    }
  ],
  "edges": [
    {
      "source": "person_1",
      "target": "company_1",
      "type": "belongs_to",
      "properties": {
        "position": "技术总监",
        "start_date": "2018-05-10"
      }
    }
  ],
  "labels": {
    "person_1": 0,
    "company_1": 1
  }
}`
    }
  ],
  execute: async (config) => {
    try {
      // 生成唯一的任务ID
      const taskId = `hgcn_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
      
      // 解析输入数据
      let graphData: {
        nodes: {id: string, type: string, properties: Record<string, any>}[],
        edges: {source: string, target: string, type?: string, properties: Record<string, any>}[],
        labels?: Record<string, number>
      };
      
      try {
        graphData = JSON.parse(config.inputData);
      } catch (e) {
        throw new Error("输入数据必须是有效的JSON格式");
      }

      // 验证输入数据结构
      if (!graphData.nodes || !Array.isArray(graphData.nodes) || !graphData.edges || !Array.isArray(graphData.edges)) {
        throw new Error("输入数据必须包含nodes和edges数组");
      }

      // 解析隐藏层维度
      let hiddenDims: number[] = [64, 32];
      if (config.hidden_layers) {
        try {
          hiddenDims = JSON.parse(config.hidden_layers);
          if (!Array.isArray(hiddenDims)) {
            hiddenDims = [64, 32];
          }
        } catch (e) {
          // 使用默认值
        }
      }
      
      // 准备所有隐藏层维度，包括输入维度
      const allDims = [Number(config.embedding_dim) || 128, ...hiddenDims];
      
      // 准备请求数据
      const requestData: AlgorithmRequest = {
        task_id: taskId,
        input_params: {
          graph: {
            nodes: graphData.nodes,
            edges: graphData.edges
          },
          hidden_dims: allDims,
          learning_rate: Number(config.learning_rate) || 0.005,
          epochs: Number(config.epochs) || 100,
          task: config.task || "community_detection",
          labels: graphData.labels
        }
      }

      // 创建任务
      const createResponse = await fetch("http://172.16.4.151:1122/api/hgcn/create", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(requestData)
      })

      if (!createResponse.ok) {
        const errorData = await createResponse.json()
        if (createResponse.status === 422) {
          const validationErrors = errorData.detail || []
          const errorMessages = validationErrors.map((err: any) => 
            `${err.loc?.join('.')}: ${err.msg}`
          ).join('\n')
          throw new Error(`数据验证错误:\n${errorMessages}`)
        }
        throw new Error(errorData.detail || "创建任务失败")
      }

      // 执行任务
      const executeResponse = await fetch(`http://172.16.4.151:1122/api/hgcn/execute/${taskId}`, {
        method: "POST"
      })

      if (!executeResponse.ok) {
        const errorData = await executeResponse.json()
        throw new Error(errorData.detail || "执行任务失败")
      }

      // 轮询获取结果
      let result
      let attempts = 0
      const maxAttempts = 60

      while (attempts < maxAttempts) {
        const getResultResponse = await fetch(`http://172.16.4.151:1122/api/hgcn/result/${taskId}`)
        
        if (!getResultResponse.ok) {
          const errorData = await getResultResponse.json()
          throw new Error(errorData.detail || "获取结果失败")
        }

        result = await getResultResponse.json()

        if (result.task_status === "COMPLETED") {
          break
        } else if (result.task_status === "FAILED") {
          throw new Error(result.error_message || "任务执行失败")
        }

        await new Promise(resolve => setTimeout(resolve, 1000))
        attempts++
      }

      if (attempts >= maxAttempts) {
        throw new Error("任务执行超时")
      }

      // 处理结果
      const outputParams = result.output_params
      
      // 统一处理结果，不再根据任务类型区分
      let resultText = "";
      let details = {};
      
      // 统计各个标签的节点数量
      const labelCounts = outputParams.predictions.reduce((acc: Record<number, number>, pred: any) => {
        const label = pred.predicted_label;
        if (!acc[label]) {
          acc[label] = 0;
        }
        acc[label]++;
        return acc;
      }, {});
      
      if (config.task === "node_classification") {
        // 节点分类任务结果处理
        const communities = Object.entries(outputParams.predictions.reduce((acc: any, pred: any) => {
          const label = pred.predicted_label;
          if (!acc[label]) {
            acc[label] = [];
          }
          acc[label].push(pred.node_id);
          return acc;
        }, {})).map(([id, nodes]: [string, any]) => ({
          id,
          nodes,
          size: nodes.length,
          stability: 1.0,
          description: `分类 ${id}`
        }));

        // 构建节点与社区的关系映射
        const nodeCommunities = outputParams.predictions.reduce((acc: any, pred: any) => {
          const nodeId = pred.node_id;
          if (!acc[nodeId]) {
            acc[nodeId] = [];
          }
          acc[nodeId].push(pred.predicted_label.toString());
          return acc;
        }, {});

        // 格式化输出文本
        resultText = `分析完成：
节点总数: ${outputParams.predictions.length}
分类类别数: ${communities.length}
分类详情: ${Object.entries(labelCounts).map(([label, count]) => `类别${label}: ${count}个节点`).join(', ')}`;

        details = {
          communities,
          node_communities: nodeCommunities,
          embeddings: outputParams.embeddings,
          metrics: result.metrics,
          predictions: outputParams.predictions
        };
      } else {
        // 社区检测任务结果处理
        const communities = Object.entries(outputParams.predictions.reduce((acc: any, pred: any) => {
          const label = pred.predicted_label;
          if (!acc[label]) {
            acc[label] = [];
          }
          acc[label].push(pred.node_id);
          return acc;
        }, {})).map(([id, nodes]: [string, any]) => ({
          id,
          nodes,
          size: nodes.length,
          stability: 1.0,
          description: `社区 ${id}`
        }));

        // 构建节点与社区的关系映射
        const nodeCommunities = outputParams.predictions.reduce((acc: any, pred: any) => {
          const nodeId = pred.node_id;
          if (!acc[nodeId]) {
            acc[nodeId] = [];
          }
          acc[nodeId].push(pred.predicted_label.toString());
          return acc;
        }, {});

        // 格式化社区详情展示
        const communitiesDetail = communities.map(community => {
          return `社区${community.id}(${community.size}个节点): ${community.nodes.join(', ')}`;
        }).join('\n');

        resultText = `社区检测完成：
检测到的社区总数: ${communities.length}
节点总数: ${outputParams.predictions.length}

社区详情:
${communitiesDetail}`;

        details = {
          communities,
          node_communities: nodeCommunities,
          embeddings: outputParams.embeddings,
          metrics: result.metrics,
          predictions: outputParams.predictions
        };
      }

      return {
        result: resultText,
        steps: result.metrics || [],
        executionTime: 0,
        details
      }
    } catch (e) {
      throw e
    }
  }
} 